package com.esl.coordinator.command;

import java.io.IOException;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.esl.coordinator.exception.STiTEQATMELIntegrationException;
import com.esl.coordinator.util.Hex;

public class CommandInvoker implements Runnable {
	public static final Logger LOG = LoggerFactory
			.getLogger(CommandInvoker.class);

	private Command command;

	public CommandInvoker(Command command) {
		this.command = command;
	}

	// sendCommand is now part of invoker object (CommandInvoker)
	// [command pattern]
	public static final String[] sendCommand(Command command)
			throws STiTEQATMELIntegrationException, IOException {
		String[] commands = command.buildCommand();
		String[] returnCommands = new String[commands.length];

		if (commands != null && commands.length > 0) {
			for (int i = 0; i < commands.length; i++) {
				String returnCommand = command.getCommandClient().sendCommand(
						Hex.toHexBytes(commands[i]),
						command.getExpectedResponseBytes());

				String noResponseReturn = Hex.toHexStringWithPadding(0,
						command.getExpectedResponseBytes());
				for (int j = 0; j < command.getRetryCount(); j++) {
					if (returnCommand.equals(noResponseReturn)) {
						returnCommand = command.getCommandClient().sendCommand(
								Hex.toHexBytes(commands[i]),
								command.getExpectedResponseBytes());
					} else {
						break;
					}
				}

				returnCommands[i] = returnCommand;
			}
		}

		command.setCommandSent(true);
		command.setCommandResponse(returnCommands);
		return returnCommands;
	}

	@Override
	public void run() {
		if (getCommand() != null) {
			try {
				Thread.sleep(getCommand().getThreadSleepTime() * 1000);
				sendCommand(getCommand());
			} catch (STiTEQATMELIntegrationException e) {
				LOG.error(
						"Command thread encountered an STiTEQATMELIntegrationExceptiono.",
						e);
			} catch (IOException e) {
				LOG.error("Command thread encountered an IOException.", e);
			} catch (InterruptedException e) {
				LOG.error(
						"Command thread encountered an InterruptedException.",
						e);
			}

		}
	}

	public Command getCommand() {
		return command;
	}

	public void setCommand(Command command) {
		this.command = command;
	}

}
